﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lilium.Web.Mvc.EntityFilters
{
	/// <summary>
	/// Default implementation of the filtering service.
	/// </summary>
	public sealed class FilteringService : IFilteringService
	{
		#region IFilteringService Members

		public void AddFilter(IEntityFilter filter)
		{
			if (filter == null) throw new ArgumentNullException("filter");

			ICollection<IEntityFilter> filters;
			if (!Filters.TryGetValue(filter.EntityType, out filters))
			{
				filters = new List<IEntityFilter>();
				Filters.Add(filter.EntityType, filters);
			}
			filters.Add(filter);
		}

		public IQueryable<TEntity> ApplyFilters<TEntity>(IQueryable<TEntity> entities)
		{
			ICollection<IEntityFilter> filters;
			if (Filters.TryGetValue(typeof(TEntity), out filters))
				return filters.Cast<IEntityFilter<TEntity>>().Aggregate(entities, (acc, filter) => filter.Apply(acc));
			else
				return entities;
		}

		#endregion

		#region private IDictionary<Type, ICollection<IEntityFilter>> Filters

		private readonly IDictionary<Type, ICollection<IEntityFilter>> m_Filters = new Dictionary<Type, ICollection<IEntityFilter>>();

		private IDictionary<Type, ICollection<IEntityFilter>> Filters
		{
			get
			{
				return m_Filters;
			}
		}

		#endregion
	}
}